iT邦幫忙

2022 iThome 鐵人賽

DAY 11
1
Software Development

軟體架構師的自我修養系列 第 11

[Day 11] 事件驅動架構的設計模式(下)

  • 分享至 

  • xImage
  •  

昨天我們介紹了要讓系統變得既可靠又有效率的一些設計模式。今天,我們繼續來討論當設計事件驅動架構時有哪些常見的處理手段。

非同步請求/回應模型

咦?請求/回應模型很常見,就是一個請求發出後等待一個回應,這是典型的同步模型。那什麼是非同步請求/回應模型?

整個時序圖如下:

伺服器是一個傳統的HTTP REST服務,並提供同步的REST API接口。客戶端一如往常的發出HTTP請求給服務端,儘管如此,服務端並不直接處理這個請求。取而代之的是,服務端將請求轉換為事件發給訊息處理者,並等待訊息處理者完成後將事件結果發回來。

透過這個設計模式,我們可以享受事件驅動架構的好處,同時依然維持客戶端和服務端的簡單同步實作。

此外,這樣的模式還有幾個額外好處。

  1. 透過訊息處理者來處理事件,那麼我們就可以透過控制處理者的數量來決定對後端系統或資料庫的壓力。在同步模型下,大量的客戶端請求進入,服務端就會生出相應的執行緒,並對後端系統施加壓力。但當事件處理者的數量是可控時,後端系統的壓力也可以得到控制。
  2. 請求去重(dedup),因為所有來自客戶端的請求都會進入訊息佇列中,那麼訊息處理者就有能力根據特定的規則進行去重複化。

緊急救護模式

緊急救護模式是為了正確處理訊息間的優先權。

一個最簡單處理緊急訊息的設計方法是總是將緊急訊息放在訊息佇列的最前端,如此一來所有處理者都可以立刻處理最緊急的訊息。

這實作有一些缺點,尤其是飢餓問題。當一直都有緊急訊息進入佇列,那意味著所有不緊急的訊息都無法被處理。因為訊息佇列的開頭總是會有緊急訊息。

為了更均勻分散訊息處理,我們可以將緊急訊息獨立出一個新的訊息佇列如下:

如此一來,處理者就能根據權重自行決定如何拿取訊息來避免飢餓問題發生。例如:權重設定成相同時,處理者就輪流從兩個訊息佇列拿取;當權重是2:1時,就會從緊急佇列拿兩個才換普通佇列拿一個。

更有甚者,我們也可以分配專職的處理者給緊急佇列。

結論

這兩個設計模式專注在解決事件驅動架構上的特定問題。

為了讓客戶端簡單實作,但我們又想保留事件驅動的彈性和低耦合,我們可以採用非同步請求/回應模式。

如果我們碰到事件的優先權問題,我們可以採用緊急救護模式。

事件驅動架構是現在系統設計的趨勢,但截至目前為止,都沒有一套解法是能夠一體適用的。因此,我們必須在眾多對應的解決方案中仔細挑選可以套用設計模式。


上一篇
[Day 10] 事件驅動架構的設計模式(上)
下一篇
[Day 12] 在程式碼中的時機耦合
系列文
軟體架構師的自我修養31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言